/**
 * MutexDbLockScan.java<br>
 *
 *
 * @version 上午11:20:43
 */
package com.iwechat.service.task;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.iwechat.mybatis.generator.model.TemplateMessage;
import com.iwechat.service.MutexDbScan;
import com.iwechat.service.TempMsgPriorityQueue;

/**
 * 数据库互斥锁实现的数据库互斥扫描
 */
@Component("mutexDbLockScanJob")
public class MutexDbLockScanJob {
    private static final Logger logger       = LogManager.getLogger();

    private static final long   initialDelay = 1 * 1000;
    private static final long   fixedDelay   = 10 * 1000;

    @Resource(name = "RedisPriorityQuenue")
    TempMsgPriorityQueue        queue;

    @Autowired
    MutexDbScan                 dbScran;

    /**
     * 扫描消息<br>
     * 5s调度一次
     */
    @Scheduled(initialDelay = initialDelay, fixedDelay = fixedDelay)
    public void scanMessage() {
        if (this.queue.getFreePercent() > 50) {
            List<TemplateMessage> messages = dbScran.scanDb();
            if (messages != null) {
                int size = messages.size();
                for (TemplateMessage mesg : messages) {
                    boolean insert = queue.offer(mesg);
                    if (!insert) {
                        synchronized (this) {
                            try {
                                this.wait(fixedDelay / size);
                                // 再不成功则忽略,会以较慢的速度逐条失败
                                queue.offer(mesg);
                            } catch (InterruptedException e) {
                            }
                        }
                    }
                }
                logger.info("scan {} messages.", size);
            }
        }
    }

    @PostConstruct
    public void init() {
        logger.info("### " + this + " init succeed!");
    }
}
